package com.briup.server;

import com.briup.Configuration;
import com.briup.entity.Environment;
import com.briup.support.ConfigurationAware;
import com.briup.support.PropertiesAware;
import com.briup.util.Backup;
import com.briup.util.Log;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;

/**
 * @Classname DBStore
 * @Description TODO
 * @Date 2023/11/21 8:15
 * @Created by 崔宗祺
 * @Version v1.0.0
 */
public class DBStoreImpl implements DBStore, PropertiesAware, ConfigurationAware {
    private Log log;
    private String driverClassName;
    private String url;
    private String username;
    private String password;
    private String filePath;
    private Backup backup;

    /**
     * 將集合对象 collection 中的一条条数据保存到数据库中
     *
     * @param collection 存储了Environment类的对象的集合
     */
    @Override
    public void saveDB(Collection<Environment> collection) throws Exception {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        int commitCount = 0;

        Collection<Environment> coll = null;
        log.info("加载数据库备份文件");
        log.debug("备份文件路径" + filePath);
        coll = (Collection<Environment>) backup.load(filePath, Backup.LOAD_REMOVE);
        if (coll != null) {
            log.info("服务器数据正在备份");
            collection.addAll(coll);
        }
        //注册驱动
        Class.forName(driverClassName);
        try {
            //获取连接
//            connection = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:XE","bttc2", "system");
            connection = DriverManager.getConnection(url,username, password);
            //设置手动提交
            connection.setAutoCommit(false);
            String sql = null;
            int day = 0;
            int dayCommitCount = 0;
            for (Environment environment : collection) {
                dayCommitCount++;
//            String gatherDate = String.valueOf(environment.getGatherDate());
//            String[] split1 = gatherDate.split("[ ]");
//            String[] split2 = split1[0].split("[-]");
//            int data = Integer.parseInt(split2[2]);
                int date = environment.getGatherDate().getDate();
                //检测  采集数据日期发生变化
                if (day != date) {
                    day = date;
                    //处理前一天 未满足的批处理阈值
                    if (preparedStatement != null) {
                        preparedStatement.executeBatch();
                        preparedStatement.clearBatch();
                        //提交前一天的数据
                        connection.commit();
                        //累加已经提交的数据
                        commitCount += dayCommitCount;
                        dayCommitCount = 0;
                        preparedStatement.close();
                    }
                    //同构语句 因为日期的变化
                    sql = "insert into e_detail_" + day + "(id,name,srcId,desId,devId,count,cmd,data,status,gatherDate) values (seq_" + day + ".nextval,?,?,?,?,?,?,?,?,?)";
                    preparedStatement = connection.prepareStatement(sql);
                }
                preparedStatement.setString(1, environment.getName());
                preparedStatement.setString(2, environment.getSrcId());
                preparedStatement.setString(3, environment.getDesId());
                preparedStatement.setString(4, environment.getDevId());
                preparedStatement.setInt(5, environment.getCount());
                preparedStatement.setString(6, environment.getCmd());
                preparedStatement.setFloat(7, environment.getData());
                preparedStatement.setInt(8, environment.getStatus());
                preparedStatement.setTimestamp(9, environment.getGatherDate());
                //添加sql到batch
                preparedStatement.addBatch();
                //因为数据量过大的批处理可能会导致数据丢失 所以每三千条处理一次
                if (dayCommitCount++ % 3000 == 0) {
                    preparedStatement.executeBatch();
                }
            }
            preparedStatement.executeBatch();
        } catch (Exception e) {
            e.printStackTrace();
            //事务回滚
            connection.rollback();
            List<Environment> collect = collection.stream().skip(commitCount).collect(Collectors.toList());
            try {
                backup.store(filePath, collect, Backup.STORE_APPEND);
            } catch (Exception e1) {
                log.debug("备份失败！");

            } finally {
                if (connection != null) {
                    connection.close();
                }
                if (preparedStatement != null) {
                    preparedStatement.close();
                }
            }
        }
    }

    @Override
    public void init(Properties properties) throws Exception {
        filePath = properties.getProperty("filePath");
        driverClassName = properties.getProperty("driverClassName");
        url = properties.getProperty("url");
        username = properties.getProperty("username");
        password = properties.getProperty("password");
    }

    @Override
    public void setConfiguration(Configuration configuration) throws Exception {
        log = configuration.getLogger();
        backup = configuration.getBackup();
    }
}
